#include <avr/wdt.h>
#include <Timer.h>
#include "Tlc5940.h"
#include "Wire.h"

#define DELAY1S     1000
#define DELAY5S     5000
#define MAX         4090
#define MIN         0
#define adres       4 //I2C adres
#define DEBUG

char instel[16];  //gevraagde actie per kanaal
char com[2];      //ontvangen bytes van de master
int waarde[16];   //ingestelde waarde op de driver
int i;
int j;
char richting[16]; //indien dimmen helderder of minder helder

Timer timer;
TLC_CHANNEL_TYPE channel;



void debug_write(String message, String header = "")
{
  #if defined(DEBUG)
    Serial.print("* DBG");
    Serial.print(header);
    Serial.print(": ");
    Serial.println(message);  
  #endif 
}

void debug_init()
{
  #if defined(DEBUG)
    Serial.begin(9600);
  #endif    
}

void other_timer()
{
for(j=1;j<16;j++)
  {
    if (instel[j]=='P') //drukknop ingedrukt
    {
      if (waarde[j]==0) //LED is uit
      {
        Tlc.set(j,4090);
        Tlc.update();
        instel[j]='R';
        waarde[j]=MAX;
      }
      else            //LED brandt
      {
        Tlc.set(j,0);
        Tlc.update();
        instel[j]='R';
        waarde[j]=MIN;
      }
    }
    if (instel[j]=='D') //LED dimmen
    {
      if (richting[j]=='U') //Helderder
      {
        if (waarde[j]<MAX) //LED brandt nog niet op max
        {
          waarde[j]=waarde[j]+10;
        }
        if (waarde[j]>=4090) //LED brandt op MAX
        {
          richting[j] = 'D';  //Minder Helder
          waarde[j]=waarde[j]-10;
        }
      }
      if (richting[j] =='D')
      {
        if (waarde[j]>MIN) //LED brandt nog
        {
          waarde[j]=waarde[j]-10;
        }
        if (waarde[j]<=0) //LED is uit
        {
          richting[j]='U';
          waarde[j]=waarde[j]+10;
        }
      }
      instel[j]='R';
      Tlc.set(j,waarde[j]);  //Stuur de waarde naar de driver
      Tlc.update();
    }
  }
}

void watchdog_timer()
{
  wdt_reset();  
}

void timer_init()
{
  int wdt_event = timer.every(DELAY1S, watchdog_timer);
  int oth_event = timer.every(DELAY5S,other_timer);
 
}

void watchdog_init()
{
  wdt_enable(WDTO_8S);
}

void setup() 
{
  timer_init();
  watchdog_init();
  Tlc.init();
  debug_init();
  Wire.begin(adres);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent);
  for(j=1;j<16;j++)
  {
    richting[j]='U'; //indien dimmen starten met helderder
    waarde[j]=Tlc.get(j); //haal de actuele waardes per kanaal op van de driver
    instel[j]='R'; //stel actie op neutraal
  }
}

void receiveEvent(int HowMany)
{
  i=1;
  while(Wire.available()) // loop through all but the last
  {
    com[i] = Wire.read(); // receive byte as a character
    //Serial.print(com[i]);     // print the character
    debug_write(com[i], "receiveEvent");
    i++;
  }
  instel[com[1]]=com[2];
}

void loop()
{
  timer.update();
}

void requestEvent() //zend status van alle kanalen naar de master
{
  char zend[16] = {waarde[1], waarde[2], waarde[3], waarde[4], waarde[5], waarde[6], waarde[7], waarde[8], waarde[9], waarde[10], waarde[11], waarde[12], waarde[13], waarde[14], waarde[15], waarde[16]};
  Wire.write (zend);
  
}
